package com.cskaoyan.user.controller;

import com.alibaba.fastjson.JSON;
import com.cskaoyan.mall.commons.result.ResponseData;
import com.cskaoyan.mall.commons.result.ResponseUtil;
import com.cskaoyan.mall.commons.util.CookieUtil;
import com.cskaoyan.mall.commons.util.jwt.JwtTokenUtils;
import com.cskaoyan.user.dto.UserLoginResponse;
import com.cskaoyan.user.dto.UserToken;
import com.cskaoyan.user.form.UserLoginRequest;
import com.cskaoyan.user.service.ILoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@Slf4j
@RestController
@RequestMapping("user")
public class LoginController {

    @Autowired
    CaptchaController captchaController;

    @Autowired
    ILoginService loginService;

    @PostMapping("login")
    public ResponseData<UserLoginResponse> userLogin(@RequestBody UserLoginRequest loginInfo, HttpServletRequest request, HttpServletResponse response) {
        // 先验证码，再验证用户信息
        String code = loginInfo.getCaptcha();

        // 如果检验码不对，自动会抛出错误，只需要调用即可
        captchaController.validKaptchaCode(code, request);

        // 到这说明验证码无误
        // 调用service层验证用户信息，取到用户的信息，如果为0条，返回对应的信息
        UserLoginResponse userLoginResponse = loginService.login(loginInfo);

        // 至此，通过验证，增加jwt
        String jwtToken = generateJwtToken(userLoginResponse, response);
        userLoginResponse.setToken(jwtToken);

        // 登陆成功，返回用户的信息
        return new ResponseUtil<UserLoginResponse>().setData(userLoginResponse);
    }

    private String generateJwtToken(UserLoginResponse userLoginResponse, HttpServletResponse response) {
        // 先生成json字符串
        UserToken userToken = new UserToken();
        userToken.setUid(userLoginResponse.getId());
        userToken.setUsername(userLoginResponse.getUsername());
        String jsonStr = JSON.toJSONString(userToken);
        // 生成jwt
        String jwtToken = JwtTokenUtils.builder().msg(jsonStr).build().creatJwtToken();
        // 放入cookie，cookie名为access_token
        Cookie access_token = CookieUtil.genCookie("access_token", jwtToken, "/", -1);
        response.addCookie(access_token);

        return jwtToken;
    }

    @GetMapping("login")
    public ResponseData<UserToken> userLoginVerify(HttpServletRequest request){
        String user_info = request.getHeader("user_info");
        UserToken userToken = JSON.parseObject(user_info, UserToken.class);
        return new ResponseUtil<UserToken>().setData(userToken);
    }

    /**
     * 用户登出：
     * 想要将之前的access_token干掉，需要指定一个同名（key相同），
     * path也要相同的cookie，并且将maxage设置为0。
     * 只有这样新的cookie才会顶掉之前的旧cookie，并且由于主动设置maxage为0
     * 浏览器才会去删除cookie，最终达到退出的效果
     *
     * 注释掉的那段代码就是一个错误的例子，
     * 虽然通过request得到cookies后遍历找到了access_token这个cookie，
     * 但是如果不主动设置path，path会是当前路径的父路径，即/user。
     * 所以浏览器内存里会存在两个path不同，但是key值相同的access_token
     *
     * 而filter每次只会取出第一个access_token，
     * 第一个access_token就是旧的那个，并且含有jwt，path为 / ，
     * 于是点击退出没有任何效果。
     *
     * @author 老朱
     */
    @GetMapping("loginOut")
    public ResponseData logout(HttpServletRequest request, HttpServletResponse response){
        // Cookie[] cookies = request.getCookies();
        // for (int i = 0; i < cookies.length; i++) {
        //     if(cookies[i].getName().equals("access_token")){
        //         cookies[i].setMaxAge(0);
        //         response.addCookie(cookies[i]);
        //         break;
        //     }
        // }
        Cookie access_token = new Cookie("access_token", null);
        access_token.setMaxAge(0);
        access_token.setPath("/");
        response.addCookie(access_token);
        return new ResponseUtil<>().setData(null);
    }

}
